/* Name: Tom Dickman
 * Date: 4/3/12
 * Description: The core of the program that performs the necessary
 * actions, including running the next event, adding events, generating
 * random events, etc. Prints the output to the GUI, and to a log file.
 * 
 * Revisions:
 * 4/3/12 - Tom Dickman - Original
 * 4/3/12 - Cameron Hoerig - Code now prints to log file correctly
 * 4/4/12 - John Gideon - Random INF initialization and random event creation
 */

import java.io.*;

public class EventExecutor {
	private Gui gui;
	private PriorityQueue priorityQueue;
	private String logfile  = "log.txt";

	// Randomly generate and add 20. Calls push
	public EventExecutor() { 
		priorityQueue = new PriorityQueue();
		
		// Create a new log file, and clear it if it already exists
		FileWriter outFile;
		try {
			outFile = new FileWriter(logfile,false);
			BufferedWriter out = new BufferedWriter(outFile);
			out.write("");
			out.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		// Randomly generate and add 20 items
		for (int i = 0; i < 20; i++) {
			// Random string of letters
			char randStr[] = new char[5];
			for (int j = 0; j < 5; j++) {
				int tmpRand = (int) (97 + (Math.random()*26));
				randStr[j] = (char) tmpRand;
			}
			// Random number between 1 and 30
			int randomInt = 1 + (int)(Math.random() * 30);
			priorityQueue.push(Integer.toString(randomInt), new String(randStr));
		}
	}
	
	// Used to pass the GUI object to this class, so output can be printed to this class.
	public void setGui(Gui uGui) {
		gui = uGui;
	}
	
	// Adds a new event to the queue
	public boolean newEvent(String priority, String info) {
		int res = priorityQueue.pushSafe(priority, info);
		if (res >= 0) {
			pushText("    New Event Added - Pr: " + priority + "  INF: " + info);
			return true;
		} else if (res == -1) {
			pushText("Invalid New Entry: Priority not a valid integer");
		} else if (res == -2) {
			pushText("Invalid New Entry: Priority is too small");
		} else if (res == -3) {
			pushText("Invalid New Entry: Priority is too large");
		} else if (res == -4) {
			pushText("Invalid New Entry: Info is not 5 characters");
		} else {
			pushText("Invalid New Entry: Unknown Error");
		}
		return false;
	}
	
	// Runs next event in the queue
	public int nextEvent() { // Runs next event
		Event nextEv = priorityQueue.pop();
		printEvent(nextEv);
		double randD = Math.random();
		if (randD < 0.5) { // 50% chance: PR + 3*PR
			int newPr = nextEv.getPriority() + 3*nextEv.getPriority();
			if (newPr > 200) {
				pushText("    A. New event PR>200, so event not created");
			} else {
				String prStr = Integer.toString(newPr);
				priorityQueue.push(prStr, nextEv.getInfo());
				pushText("    A. New Event Created - Pr: " + prStr + "  INF: " + nextEv.getInfo());
			}
		} else if (randD < 0.8) { // 30% chance: PR + 10*PR
			int newPr = nextEv.getPriority() + 10*nextEv.getPriority();
			if (newPr > 200) {
				pushText("    B. New event PR>200, so event not created");
			} else {
				String prStr = Integer.toString(newPr);
				priorityQueue.push(prStr, nextEv.getInfo());
				pushText("    B. New Event Created - Pr: " + prStr + "  INF: " + nextEv.getInfo());
			}
		} else { // 20% chance: no new event
			pushText("    C. No new event was created");
		}     
		return priorityQueue.getSize();
	}
	
	// Empties out rest of priority queue - prints out to GUI
	public void stopEvent() { 
		EventExecutorThread myThread = new EventExecutorThread(this);
		myThread.start();
	}
	
	// Print the given event to the GUI using pushText
	public void printEvent(Event event) {
		String priority = Integer.toString(event.getPriority());
		String info = event.getInfo();
		pushText("Event Executed - Pr: " + priority + "  INF: " + info);
	}
	
	// Pushes the given text to the gui, saving it in the log file, and displaying it on screen
	public void pushText(String theText) {
		gui.pushText(theText);
		//try {
		try{
		    FileWriter outFile = new FileWriter(logfile,true);
			BufferedWriter out = new BufferedWriter(outFile);
			out.write(theText);
			out.newLine();
			out.close();
		}
		catch(IOException e){
			e.printStackTrace();
		}
	}
	
	// Returns the current priority queue - created for EventExecutorThread
	public PriorityQueue getPriorityQueue() {
		return priorityQueue;
	}
}
